{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Notebook 7 - Search of products in PubChem"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%run ../common.py"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [],
   "source": [
    "df_products = pd.read_csv(filepath_results + 'Substrates_VB_clean.csv', encoding='utf8', usecols=('Name',))\n",
    "df_products = df_products.drop_duplicates('Name', ignore_index=True)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [],
   "source": [
    "import requests\n",
    "\n",
    "def wildcard_search_pubchem(query):\n",
    "    base_url = \"https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi\"\n",
    "    params = {\n",
    "        \"db\": \"pccompound\",\n",
    "        \"term\": f\"{query} *glucoside\",\n",
    "        \"retmode\": \"json\",\n",
    "    }\n",
    "    \n",
    "    response = requests.get(base_url, params=params)\n",
    "    \n",
    "    if response.status_code == 200:\n",
    "        data = response.json()\n",
    "        if 'esearchresult' in data and 'idlist' in data['esearchresult']:\n",
    "            cids = data['esearchresult']['idlist']\n",
    "            return cids\n",
    "        else:\n",
    "            return []\n",
    "    else:\n",
    "        return []\n",
    "\n",
    "def get_compound_names(cids):\n",
    "    names = {}\n",
    "    if not cids:\n",
    "        return names\n",
    "    \n",
    "    # Request compound names based on CIDs\n",
    "    cid_list = \",\".join(cids)\n",
    "    base_url = f\"https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/cid/{cid_list}/property/IUPACName/JSON\"\n",
    "    \n",
    "    response = requests.get(base_url)\n",
    "    \n",
    "    if response.status_code == 200:\n",
    "        data = response.json()\n",
    "        if 'PropertyTable' in data and 'Properties' in data['PropertyTable']:\n",
    "            for compound in data['PropertyTable']['Properties']:\n",
    "                cid = compound.get('CID')\n",
    "                name = compound.get('IUPACName')\n",
    "                names[cid] = name\n",
    "    return names"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|██████████| 434/434 [02:55<00:00,  2.47it/s]\n"
     ]
    }
   ],
   "source": [
    "query_strings = df_products['Name'].to_list()\n",
    "cids = []\n",
    "names = []\n",
    "for query in tqdm(query_strings):\n",
    "    cid = wildcard_search_pubchem(query)\n",
    "    name = get_compound_names(cid)\n",
    "    cids.append(cid)\n",
    "    names.append(name)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [],
   "source": [
    "df_products['Product_Name'] = [list(name.values()) for name in names]\n",
    "df_products['CID'] = cids"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [],
   "source": [
    "df_products['in_pubchem'] = [bool(x) for x in df_products['CID']]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "in_pubchem\n",
       "False    358\n",
       "True      76\n",
       "Name: count, dtype: int64"
      ]
     },
     "execution_count": 37,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df_products['in_pubchem'].value_counts()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 68,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Let us add a column indicating how many enzymes turned over each substrate\n",
    "\n",
    "df_sd = pd.read_csv(filepath_results + 'Screening_results_CosineScore_0.85.csv')\n",
    "df_sd = df_sd.drop_duplicates(['Name', 'Enzyme_name'])\n",
    "enzymes_react = dict(df_sd['Name'].value_counts())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [],
   "source": [
    "df_products['Enzymes_react'] = df_products['Name'].apply(lambda x: enzymes_react.get(x, 0))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [],
   "source": [
    "df_products['reacted'] = df_products['Enzymes_react'] > 0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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Q1dERESVREhICHr16qXXe2bPno1Fixap3+fl5YXY2Fh8/fXXGDJkiCHKlBWDDhERUSXRokULvZbPyMhASkoKhg8fjhEjRqjb8/Ly4ODgIHd5BsGgQ0REVEnY2NhoTJuYmGg9oSA3N1f974KCAgBPD1/961//0ljO1NTUQFXKi0GHiIioknJ2dsbNmzchhFBfnh4TE6Oe7+Ligpo1a+Lq1asYOHCgkaosHQYdIiKiSsrf3x8ZGRlYuHAhevfujcjISOzduxf29vbqZcLDwxEcHAx7e3t069YNOTk5iIqKQmZmpvph3OUZgw4REVExValeS6+b+MkxniH5+Phg1apVmDt3LmbPno33338fn332GdasWaNe5qOPPoK1tTW+/PJLTJw4ETY2NvD19UVISIhBa5OLJPR5fHgFlJWVBQcHB5wP84GdpebxxE6rEmE/SPteAHnH1uLvP4+UVYlERGQkjx8/RmJiIry8vGBpaWnsciqdF33+hX+/7927p/ENk754Hx0iIiJSLAYdIiIiUiwGHSIiIlIsBh0iIiJSLAYdIiKq9ApvjEdlqyw+d15eTkRElZaFhQVMTExw48YNODs7w8LCQn3jPDIcIQSePHmCjIwMmJiYwMLCwmBjMegQEVGlZWJiAi8vL6SlpeHGjRvGLqfSsba2Ru3atWFiYrgDTAw6RERUqVlYWKB27drIy8tDfn6+scupNExNTWFmZmbwb9AYdIiIqNKTJAnm5uYwNzc3dikkM56MTERERIrFoENERESKxaBDREREisWgQ0RERIrFoENERESKxaBDREREisWgQ0RERIrFoENERESKxaBDREREisWgQ0RERIrFoENERESKxaBDREREimXUoPP777+jR48ecHNzgyRJ2Llzp3pebm4uJk2aBF9fX9jY2MDNzQ2DBw/GjRs3jFcwERERVShGDTrZ2dlo0qQJVqxYoTXv4cOHOH36NKZNm4bTp09j+/btuHTpEt555x0jVEpEREQVkZkxB+/WrRu6deumc56DgwMOHDig0bZ8+XK89tprSE5ORu3atcuiRCIiIqrAjBp09HXv3j1IkgRHR8cil8nJyUFOTo56OisrqwwqIyIiovKowpyM/PjxY0yePBkDBgyAvb19kcvNmzcPDg4O6pe7u3sZVklERETlSYUIOrm5uejXrx8KCgqwatWqFy4bFhaGe/fuqV8pKSllVCURERGVN+X+0FVubi769u2LxMRE/Pbbby/8NgcAVCoVVCpVGVVHRERE5Vm5DjqFISchIQGHDh2Ck5OTsUsiIiKiCsSoQefBgwe4fPmyejoxMRExMTGoWrUq3Nzc0Lt3b5w+fRq//PIL8vPzcfPmTQBA1apVYWFhYayyiYiIqIIwatCJiopCx44d1dOhoaEAgCFDhiA8PBy7du0CAPj5+Wm879ChQ/D39y+rMomIiKiCMmrQ8ff3hxCiyPkvmkdERET0MhXiqisiIiKikmDQISIiIsVi0CEiIiLFYtAhIiIixWLQISIiIsVi0CEiIiLFYtAhIiIixWLQISIiIsVi0CEiIiLFYtAhIiIixWLQISIiIsUqddDJz89HTEwMMjMz5aiHiIiISDZ6B52QkBCsXbsWwNOQ06FDBzRr1gzu7u44fPiw3PURERERlZjeQWfbtm1o0qQJAGD37t1ITExEfHw8QkJCMHXqVNkLJCIiIiopvYPO7du34erqCgDYs2cP+vTpg3r16mH48OE4d+6c7AUSERERlZTeQcfFxQWxsbHIz89HZGQkOnfuDAB4+PAhTE1NZS+QiIiIqKTM9H3D0KFD0bdvX9SoUQOSJKFLly4AgL/++gv169eXvUBjSElKQpPWHTTaaro4Y8/ObUaqiIiIiEpC76ATHh6ORo0aISUlBX369IFKpQIAmJqaYvLkybIXaAz5kgnM2g3XaEs9ttZI1RAREVFJ6R10AKB3794AgMePH6vbhgwZIk9FRERERDLR+xyd/Px8zJ49GzVr1oStrS2uXr0KAJg2bZr6snMiIiKi8kDvoDNnzhxs2LABCxcuhIWFhbrd19cX3377razFEREREZWG3kFn06ZNWLNmDQYOHKhxlVXjxo0RHx8va3FEREREpaF30ElNTYW3t7dWe0FBAXJzc2UpioiIiEgOegedhg0b4ujRo1rt//3vf9G0aVNZiiIiIiKSg95XXc2YMQODBg1CamoqCgoKsH37dly8eBGbNm3CL7/8YogaiYiIiEpE7290evToga1bt2LPnj2QJAnTp09HXFwcdu/erb55IBEREVF5UKL76AQEBCAgIEDuWoiIiIhkpfc3OnXq1MGdO3e02v/55x/UqVNHlqKIiIiI5KB30Ll27Rry8/O12nNycpCamipLUURERERyKPahq127dqn/vW/fPjg4OKin8/PzcfDgQXh6espaHBEREVFpFDvovPvuuwAASZK0nmtlbm4OT09PLFq0SNbiiIiIiEqj2EGnoKAAAODl5YVTp06hWrVqBiuKiIiISA56X3WVmJhoiDqIiIiIZFeiy8uzs7Nx5MgRJCcn48mTJxrzgoODZSmMiIiIqLT0DjpnzpxB9+7d8fDhQ2RnZ6Nq1aq4ffs2rK2tUb16dQYdIiIiKjf0vrx83Lhx6NGjB+7evQsrKyucOHECSUlJaN68Of7973/r1dfvv/+OHj16wM3NDZIkYefOnRrzhRAIDw+Hm5sbrKys4O/vjwsXLuhbMhEREVVSegedmJgYjB8/HqampjA1NUVOTg7c3d2xcOFCTJkyRa++srOz0aRJE6xYsULn/IULF2Lx4sVYsWIFTp06BVdXV3Tp0gX379/Xt2wiIiKqhPQ+dGVubg5JkgAALi4uSE5Oho+PDxwcHJCcnKxXX926dUO3bt10zhNCYOnSpZg6dSp69eoFANi4cSNcXFywefNmjBw5Ut/SiYiIqJLR+xudpk2bIioqCgDQsWNHTJ8+HT/88ANCQkLg6+srW2GJiYm4efMmunbtqm5TqVTo0KED/vjjjyLfl5OTg6ysLI0XERERVU56B525c+eiRo0aAIDZs2fDyckJn376KdLT07FmzRrZCrt58yaAp98aPcvFxUU9T5d58+bBwcFB/XJ3d5etJiIiIqpY9Dp0JYSAs7MzGjZsCABwdnbGnj17DFJYocLDZM/W8Hzbs8LCwhAaGqqezsrKYtghIiKqpPT6RkcIgbp16+L69euGqkfN1dUVALS+vUlPT9f6ludZKpUK9vb2Gi8iIiKqnPQKOiYmJqhbty7u3LljqHrUvLy84OrqigMHDqjbnjx5giNHjqBNmzYGH5+IiIgqPr3P0Vm4cCEmTJiA8+fPl3rwBw8eICYmBjExMQCenoAcExOD5ORkSJKEkJAQzJ07Fzt27MD58+cRGBgIa2trDBgwoNRjExERkfLpfXn5hx9+iIcPH6JJkyawsLCAlZWVxvy7d+8Wu6+oqCh07NhRPV14bs2QIUOwYcMGTJw4EY8ePcKoUaOQmZmJf/3rX9i/fz/s7Oz0LZuIiIgqIb2DzpIlS154MrA+/P39IYQocr4kSQgPD0d4eLgs4xEREVHlonfQCQwMNEAZRERERPLT+xwdU1NTpKena7XfuXMHpqamshRFREREJAe9g05Rh5pycnJgYWFR6oKIiIiI5FLsQ1dfffUVgKfnzXz77bewtbVVz8vPz8fvv/+O+vXry18hERERUQkVO+gsWbIEwNNvdFavXq1xmMrCwgKenp5YvXq1/BUSERERlVCxg05iYiKApw/y3L59O6pUqWKwooiIiIjkoPc5OocOHdIIOfn5+YiJiUFmZqashRERERGVlt5BJyQkBGvXrgXwNOS0b98ezZo1g7u7Ow4fPix3fUREREQlpnfQ+e9//4smTZoAAHbv3o1r164hPj4eISEhmDp1quwFEhEREZWU3kHnzp076ieL79mzB3369EG9evUwfPhwnDt3TvYCiYiIiEpK76Dj4uKC2NhY5OfnIzIyEp07dwYAPHz4kDcMJCIionJF70dADB06FH379kWNGjUgSRK6dOkCAPjrr794Hx0iIiIqV/QOOuHh4WjUqBFSUlLQp08fqFQqAE8fDTF58mTZCyQiIiIqKb2DDgD07t1bq23IkCGlLoaIiIhITnqfowMABw8exNtvv41XXnkF3t7eePvtt/G///1P7tqIiIiISkXvoLNixQq8+eabsLOzw9ixYxEcHAx7e3t0794dK1asMESNRERERCWi96GrefPmYcmSJRg9erS6LTg4GG3btsWcOXM02iuz7u/2RuqtDK32mi7O2LNzmxEqIiIiqnz0DjpZWVl48803tdq7du2KSZMmyVKUEqTeyoBZu+Ha7cfWGqEaIiKiyknvQ1fvvPMOduzYodX+888/o0ePHrIURURERCSHYn2j89VXX6n/7ePjgzlz5uDw4cNo3bo1AODEiRM4fvw4xo8fb5gqiYiIiEqgWEFnyZIlGtNVqlRBbGwsYmNj1W2Ojo5Yt24dPv/8c3krJCIiIiqhYgWdxMREQ9dBREREJLsS3UeHiIiIqCLQ+6qrYcOGvXD+unXrSlwMERERkZz0DjqZmZka07m5uTh//jz++ecfvPHGG7IVRkRERFRaegcdXZeWFxQUYNSoUahTp44sRRERERHJQZZzdExMTDBu3Ditq7OIiIiIjEm2k5GvXLmCvLw8ubojIiIiKjW9D12FhoZqTAshkJaWhl9//RVDhgyRrTAiIiKi0tI76Jw5c0Zj2sTEBM7Ozli0aNFLr8giIiIiKkt6B51Dhw4Zog4iIiIi2el9js6j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5eWVuigiIiIiORQ76OzYsaPIeX/88QeWL18OIYQsRZG8UpKS0KR1B632mi7O2LNzmxEqMozu7/ZG6q0MrXalrScRERVfsYNOz549tdri4+MRFhaG3bt3Y+DAgZg9e7asxZE88iUTmLUbrtWeemytEaoxnNRbGZViPYmIqPhKdI7OjRs3MGLECDRu3Bh5eXmIiYnBxo0bUbt2bbnrIyIiIioxvYLOvXv3MGnSJHh7e+PChQs4ePAgdu/ejUaNGhmqPiIiIqISK/ahq4ULF2LBggVwdXXFli1bdB7KIiIiIipPih10Jk+eDCsrK3h7e2Pjxo3YuHGjzuW2b98uW3FEREREpVHsoDN48OCXXl5OREREVJ4UO+hs2LDBgGUQERERyY93RiYiIiLFYtAhIiIixWLQISIiIsVi0CEiIiLFYtAhIiIixWLQISIiIsVi0CEiIiLFYtAhIiIixWLQISIiIsVi0CEiIiLFYtAhIiIixWLQISIiIsWqUEFn3rx5kCQJISEhxi6FiIiIKoAKE3ROnTqFNWvWoHHjxsYuhYiIiCqIChF0Hjx4gIEDB+Kbb75BlSpVjF0OERERVRAVIugEBQXhrbfeQufOnV+6bE5ODrKysjReREREVDmZGbuAl/nPf/6D06dP49SpU8Vaft68eZg5c2axln3yJBePfp6m1W71+K5WW0pSEpq07qDVfj01DZ7FGu3F/dR0ccaendtK1Ye+tRARESlduQ46KSkpGDt2LPbv3w9LS8tivScsLAyhoaHq6aysLLi7u+tc1srCBJEf2mu1d1p1R6stXzKBWbvhWu15m8OLVdfL+kk9trbUfehbCxERkdKV66ATHR2N9PR0NG/eXN2Wn5+P33//HStWrEBOTg5MTU013qNSqaBSqcq6VCIiIiqHynXQ6dSpE86dO6fRNnToUNSvXx+TJk3SCjlEREREzyrXQcfOzg6NGjXSaLOxsYGTk5NWOxEREdHzKsRVV0REREQlUa6/0dHl8OHDxi6BiIiIKgh+o0NERESKxaBDREREisWgQ0RERIrFoENERESKxaBDREREisWgQ0RERIrFoENERESKxaBDREREisWgQ0RERIrFoENERESKxaBDREREisWgQ0RERIrFoENERESKxaBDREREisWgQ0RERIrFoENERESKZWbsAsqjJ09y8ejnaRptVo/vGnTMlKQkNGndQaPtemoaPA06KhERkbIx6OhgZWGCyA/tNdo6rbpj0DHzJROYtRuu0Za3OdygYxIRESkdD10RERGRYjHoEBERkWIx6BAREZFiMegQERGRYjHoEBERkWIx6BAREZFiMegQERGRYjHoEBERkWIx6BAREZFiMegQERGRYjHoEBERkWIx6BAREZFiMegQERGRYjHoEBERkWIx6BAREZFiMegQERGRYjHoEBERkWKV66Azb948tGzZEnZ2dqhevTreffddXLx40dhlERERUQVRroPOkSNHEBQUhBMnTuDAgQPIy8tD165dkZ2dbezSiIiIqAIwM3YBLxIZGakxvX79elSvXh3R0dFo3769kaoiIiKiiqJcB53n3bt3DwBQtWrVIpfJyclBTk6OejorK8vgdREREVH5VGGCjhACoaGhaNeuHRo1alTkcvPmzcPMmTNlH//Jk1w8+nmaVrvV47s6l7d6nKFzeduHt/Tqx5B9Z1w6jQa1HDXahLkN4hJTi11LUXy8akLK1T7EeO9xAarVbarRVtPFGXt2bit2393f7Y3UWxla7ddT0+Cpd6XF61vfGsv7mMZQWdZTLgPe647M9OsabVWq18LmHXtK1UdJ+tFFru1Z3veL8l4fUDFqNKYKE3RGjx6Ns2fP4tixYy9cLiwsDKGhoerprKwsuLu7l3p8KwsTRH5or9XeadUdncvbmQudy3ddla5XP4bs28ZcIPJjzc/mzTUpxa7jRaTcbK2+n9aSCLN2wzXaUo+t1avv1FsZWn0AQN7mcL360advfWss72MaQ2VZT7lkpl/H1wFCo23kPu3Qom8fJelHF7m2Z3nfL8p7fUDFqNGYKkTQGTNmDHbt2oXff/8dtWrVeuGyKpUKKpWqjCojIiKi8qxcBx0hBMaMGYMdO3bg8OHD8PLyMnZJREREVIGU66ATFBSEzZs34+eff4adnR1u3rwJAHBwcICVlZWRqyMiIqLyrlzfRyciIgL37t2Dv78/atSooX5t3brV2KURERFRBVCuv9ERQvskOiIiIqLiKtff6BARERGVBoMOERERKRaDDhERESkWgw4REREpFoMOERERKRaDDhERESkWgw4REREpFoMOERERKRaDDhERESkWgw4REREpFoMOERERKRaDDhERESkWgw4REREpFoMOERERKRaDDhERESkWgw4REREplpmxC6jonjzJxaOfp2m1SyK/1H1bPc4wWN9FefjoMbq1bazVfvfSZdjduabV/s+du2jSuoNWe26+7hp1fV5ZGbfQoJaj1rL3HhegWt2mWu3XU9Pgqbt8nTIundbqX9++U5KSdK5netoNVK/hptVe08UZe3Zu02jr/m5vpN7KKBdj6tMHAAx4rzsy069rtVepXgubd+zRUb3h6Fqnotbnyc3L8HRz0movqm4fr5qQcrO12h/m5MKn3isabdfT0lGrRnWtZa/duAMLV2+t9tsJZ+Bgqf1/S2Fug7jEVK12XeIvXtbrZ+XRtURAx96VmnqjWOMBRW/7rOQ0VNWxfFH7bVH7VlZyLKx0/J7T9XuhqM+qqP1c3/057tIVWKvMNevIfgx7Hb/7HmU/1GorCV37nD77REVWVr9XGHRKycrCBJEf2mu1d12VXuq+7cyFwfouipW5hK8DhFZ7wBXdtXRadQdm7YZrd5QYrbt/HZ9X11XpiPzYXUffiTr7ztscXkT1utmYC63+9e07XzLRufzDzeE621OPrdVuu5VRbsbUpw8AyEy/rnO/GLlP+5eUoelap6LWJ3dLML4O0P5zXFTdUm62zn0xYNVlrfV/65uHOj+TN9dk66zFOnEUIj/20LF8is5adLE0096XgaL3Z1HEz2FeXl6xxyxq27+5Jlfn8kXtt0XtW1ZSbpG/555f16I+q6L2c33354ArBVpjdl11WWd9b665p7Nvfena5/TZJyqysvq9wkNXREREpFgMOkRERKRYDDpERESkWAw6REREpFgMOkRERKRYDDpERESkWAw6REREpFgMOkRERKRYDDpERESkWAw6REREpFgMOkRERKRYDDpERESkWAw6REREpFgMOkRERKRYDDpERESkWAw6REREpFgMOkRERKRYFSLorFq1Cl5eXrC0tETz5s1x9OhRY5dEREREFUC5Dzpbt25FSEgIpk6dijNnzuD1119Ht27dkJycbOzSiIiIqJwr90Fn8eLFGD58OD766CP4+Phg6dKlcHd3R0REhLFLIyIionLOzNgFvMiTJ08QHR2NyZMna7R37doVf/zxh8735OTkICcnRz197949AMCDnHytZfMLBO4/Ll67PsuWpL2gQCA/55FWm6H6Lqp/Q/ZdVD/69i0KCvRq11WLXH0X1Z6fl4esrCytNqmcj6mrDwDIy8vH/cdCR7ukc3ld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sXDhQgDAokWL4O7ujvbt22PAgAH47LPPjHbvGy8vL2zbtg3bt29H48aNERERgalTpwLQPtRYqPDy+CpVqqB9+/bo3Lkz6tSpg61bt2osZ29vjx49euDvv//GwIEDNebJud+uW7cOmZmZaNq0KQYNGoTg4GBUr169yOWtra0RHx+P999/H/Xq1cPHH3+M0aNHqw+tBQQEYNq0aZg4cSJatmyJ+/fvY/DgwVr9DB48GI8ePcJrr72GoKAgjBkzRn2zxpftK5999hlMTU3RoEEDODs7v/B8myVLlqBKlSpo06YNevTogYCAADRr1kxjmVmzZuHatWt45ZVX1OeyvWx/popFEi87qExEipOSkgJPT0+cOnVK6xc/ldycOXOwevVqpKSkGLsUIvr/eI4OUSWSm5uLtLQ0TJ48Ga1atWLIKaVVq1ahZcuWcHJywvHjx/Hll19q3ZCRiIyLQYeoEjl+/Dg6duyIevXqadxxmUomISEBX3zxBe7evYvatWtj/PjxCAsLM3ZZRPQMHroiIiIixeLJyERERKRYDDpERESkWAw6REREpFgMOkRERKRYDDpERESkWAw6REREpFgMOkRERKRYDDpERESkWP8Pw1PSvvUDHv0AAAAASUVORK5CYII=",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "sns.countplot(x='Enzymes_react', \n",
    "              hue='in_pubchem', \n",
    "              data=df_products,\n",
    "              dodge=False,\n",
    "              native_scale=True,\n",
    "              edgecolor='k',\n",
    "              width=1.0,\n",
    "              linewidth=0.5)\n",
    "plt.ylim([0,16])\n",
    "plt.xlim([-0.5,85])\n",
    "plt.xlabel('Number of enzymes turning over a substrate')\n",
    "plt.ylabel('Number of substrates')\n",
    "plt.xticks(rotation=90)\n",
    "plt.xticks(range(0, 86, 5))\n",
    "plt.yticks(range(0, 16, 2))\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [],
   "source": [
    "df_products.to_csv(filepath_results + 'potential_products_pubchem.csv', index=False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [],
   "source": [
    "df_products = pd.read_csv(filepath_results + 'potential_products_pubchem.csv')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th>in_pubchem</th>\n",
       "      <th>False</th>\n",
       "      <th>True</th>\n",
       "      <th>All</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>reacted</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>False</th>\n",
       "      <td>218</td>\n",
       "      <td>29</td>\n",
       "      <td>247</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>True</th>\n",
       "      <td>140</td>\n",
       "      <td>47</td>\n",
       "      <td>187</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>All</th>\n",
       "      <td>358</td>\n",
       "      <td>76</td>\n",
       "      <td>434</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "in_pubchem  False  True  All\n",
       "reacted                     \n",
       "False         218    29  247\n",
       "True          140    47  187\n",
       "All           358    76  434"
      ]
     },
     "execution_count": 44,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "### Figure 2b\n",
    "\n",
    "pd.crosstab(df_products['reacted'], df_products['in_pubchem'], margins=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python [conda env:base] *",
   "language": "python",
   "name": "conda-base-py"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
